// 指定包名，管理通用返回结构类的归属
package com.example.ossmultipart.util; // 统一结果返回类所在包

// 导入可序列化接口，使返回对象可在网络传输或持久化时序列化
import java.io.Serializable; // 序列化接口导入
// 导入 Map，用于存放额外扩展数据
import java.util.HashMap; // HashMap 导入用于 extra 存储
import java.util.Map; // Map 接口导入

// 泛型统一返回结构，支持自定义数据类型
public class Msg<T> implements Serializable { // 定义通用返回类，并实现序列化接口

    // 序列化版本号，确保不同环境反序列化兼容
    private static final long serialVersionUID = 1L; // 固定序列化ID

    // 状态码，如 200 表示成功、500 表示失败
    private int code; // 业务状态码字段
    // 文本消息，描述操作结果或错误信息
    private String message; // 结果消息字段
    // 泛型数据载体，用于返回具体数据内容
    private T data; // 返回数据字段
    // 服务器当前时间戳，便于客户端记录或追踪
    private long timestamp; // 时间戳字段
    // 额外扩展数据，存放一些非核心但有用的键值对
    private Map<String, Object> extra; // 扩展数据字段

    // 私有构造方法，禁止外部直接实例化，统一通过工厂方法创建
    private Msg() { // 构造方法私有化
        this.timestamp = System.currentTimeMillis(); // 初始化时间戳为当前时间
    } // 私有构造方法结束

    // 私有构造方法，带状态码与消息
    private Msg(int code, String message) { // 构造方法：状态码 + 消息
        this(); // 调用无参构造初始化时间戳
        this.code = code; // 设置状态码
        this.message = message; // 设置消息文本
    } // 构造方法结束

    // 私有构造方法，带状态码、消息与数据
    private Msg(int code, String message, T data) { // 构造方法：状态码 + 消息 + 数据
        this(code, message); // 复用另一个构造方法设置状态码与消息
        this.data = data; // 设置返回数据
    } // 构造方法结束

    // 成功-无数据的工厂方法，默认消息“操作成功”
    public static <T> Msg<T> success() { // 创建成功消息（无数据）
        return new Msg<>(200, "操作成功"); // 返回 code=200 的结果
    } // 方法结束

    // 成功-自定义消息的工厂方法
    public static <T> Msg<T> success(String message) { // 创建成功消息（自定义文本）
        return new Msg<>(200, message); // 返回自定义消息的成功结果
    } // 方法结束

    // 成功-携带数据的工厂方法
    public static <T> Msg<T> success(T data) { // 创建成功消息（携带数据）
        return new Msg<>(200, "操作成功", data); // 返回成功并附带数据
    } // 方法结束

    // 成功-自定义消息 + 数据的工厂方法
    public static <T> Msg<T> success(String message, T data) { // 创建成功消息（自定义文本 + 数据）
        return new Msg<>(200, message, data); // 返回自定义消息与数据的成功结果
    } // 方法结束

    // 失败-默认消息的工厂方法
    public static <T> Msg<T> fail() { // 创建失败消息（默认文本）
        return new Msg<>(500, "操作失败"); // 返回 code=500 的结果
    } // 方法结束

    // 失败-自定义消息的工厂方法
    public static <T> Msg<T> fail(String message) { // 创建失败消息（自定义文本）
        return new Msg<>(500, message); // 返回自定义失败消息
    } // 方法结束

    // 失败-自定义状态码 + 消息的工厂方法
    public static <T> Msg<T> fail(int code, String message) { // 创建失败消息（自定义状态码 + 文本）
        return new Msg<>(code, message); // 返回指定状态码的失败结果
    } // 方法结束

    // 链式设置：状态码
    public Msg<T> code(int code) { // 链式方法设置状态码
        this.code = code; // 更新状态码
        return this; // 返回当前对象以支持链式调用
    } // 方法结束

    // 链式设置：消息文本
    public Msg<T> message(String message) { // 链式方法设置消息文本
        this.message = message; // 更新消息文本
        return this; // 返回当前对象以支持链式调用
    } // 方法结束

    // 链式设置：返回数据
    public Msg<T> data(T data) { // 链式方法设置返回数据
        this.data = data; // 更新数据字段
        return this; // 返回当前对象以支持链式调用
    } // 方法结束

    // 链式设置：扩展数据（键值对）
    public Msg<T> extra(String key, Object value) { // 链式方法添加额外数据
        if (this.extra == null) { // 若尚未初始化扩展数据 Map
            this.extra = new HashMap<>(); // 创建新的 HashMap 存储扩展键值
        } // if 结束
        this.extra.put(key, value); // 将键值对放入扩展数据
        return this; // 返回当前对象以支持链式调用
    } // 方法结束

    // Getter 方法：状态码
    public int getCode() { // 获取状态码
        return code; // 返回当前状态码
    } // 方法结束

    // Getter 方法：消息文本
    public String getMessage() { // 获取消息文本
        return message; // 返回当前消息文本
    } // 方法结束

    // Getter 方法：数据
    public T getData() { // 获取返回数据
        return data; // 返回当前数据
    } // 方法结束

    // Getter 方法：时间戳
    public long getTimestamp() { // 获取时间戳
        return timestamp; // 返回当前时间戳
    } // 方法结束

    // Getter 方法：扩展数据 Map
    public Map<String, Object> getExtra() { // 获取扩展数据
        return extra; // 返回扩展数据 Map
    } // 方法结束

    // 重写 toString 方法，便于日志输出与调试
    @Override // 表示覆盖父类方法
    public String toString() { // 自定义对象转字符串方法
        return "Msg{" + // 输出类名与花括号开始
                "code=" + code + // 拼接状态码
                ", message='" + message + '\'' + // 拼接消息文本
                ", data=" + data + // 拼接数据
                ", timestamp=" + timestamp + // 拼接时间戳
                ", extra=" + extra + // 拼接扩展数据
                '}'; // 结束花括号
    } // 方法结束
} // 类结束